package dfl.bysj.controller;


import cn.hutool.system.UserInfo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import dfl.bysj.config.RedisKey;
import dfl.bysj.config.model.VO.UserDto;
import dfl.bysj.entity.*;
import dfl.bysj.entity.VO.StudentVO;
import dfl.bysj.entity.VO.UpdateBindVO;
import dfl.bysj.exception.Assert;
import dfl.bysj.exception.UnifiedException;
import dfl.bysj.handler.NoAuth;
import dfl.bysj.mapper.UpdateBindMapper;
import dfl.bysj.result.R;
import dfl.bysj.result.ResponseEnum;
import dfl.bysj.service.*;
import dfl.bysj.util.JWTUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author DFL
 * @since 2022-04-26
 */
@Slf4j
@RestController
@RequestMapping("/student")
public class StudentController {

    private GradeService gradeService;

    private AcademyService academyService;

    @Autowired
    private StudentService studentService;

    private RedisTemplate redisTemplate;

    private UserService userService;

    private StudentSeatRelationService studentSeatRelationService;

    private UserTeacherStudentService userTeacherStudentService;

    private UpdateBindService updateBindService;


    private UpdateInformationService updateInformationService;

    @Autowired
    public void setUpdateInformationService(UpdateInformationService updateInformationService) {
        this.updateInformationService = updateInformationService;
    }

    @Autowired
    public void setUpdateBindService(UpdateBindService updateBindService) {
        this.updateBindService = updateBindService;
    }

    @Autowired
    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Autowired
    public void setUserTeacherStudentService(UserTeacherStudentService userTeacherStudentService) {
        this.userTeacherStudentService = userTeacherStudentService;
    }

    @Autowired
    public void setStudentSeatRelationService(StudentSeatRelationService studentSeatRelationService) {
        this.studentSeatRelationService = studentSeatRelationService;
    }

    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

//    @Autowired
//    public void setStudentService(StudentService studentService) {
//        this.studentService = studentService;
//    }

    @Autowired
    public void setAcademyService(AcademyService academyService) {
        this.academyService = academyService;
    }

    @Autowired
    public void setGradeService(GradeService gradeService) {
        this.gradeService = gradeService;
    }

    @NoAuth
    @ApiOperation("注册初始化")
    @RequestMapping("/regist_index")
    public R regist_index(){
        Map<String, Object> resMap=new HashMap<>();
        resMap.put("gradeList", gradeService.getALLGrade());
        resMap.put("academyList",academyService.getAllAcademy());
        return R.ok().data(resMap);
    }

    @NoAuth
    @ApiOperation("注册")
    @PostMapping("/regist")
    public R regist(StudentVO studentVO){
        /**
         * 通过获取StudentVo的String,判断是否有null或空值
         */
        String checkString=studentVO.toString();
        if (checkString.contains("null")){
            throw new UnifiedException(ResponseEnum.STUDENT_TEACHER_INFO_NOT_OVER);
        }

        return R.ok().data("registStu",userService.regist_student(studentVO));
    }

    @NoAuth
    @GetMapping("/regist/grades")
    public R regist_grade(String academy){
        Assert.notNull(academy, ResponseEnum.ERROR);
        Academy academy1=academyService.getAcademyByacaName(academy);
        Assert.notNull(academy1, ResponseEnum.BAD_SQL_GRAMMAR_ERROR);
        return R.ok().data("gradeListAca",gradeService.getGradesByAcaId(academy1.getAcaId()));
    }



    /**
     * 修改绑定
     * 1、从前端获取修改的信息以及token
     * 2、判断token以及修改信息是否为null
     * 3、解析token，token正确才可继续
     * 4、删除该token对应的学生下的座位预约信息（token加上相关信息是肯定可以在redis中找到）
     * 5、将修改前的学生id、修改后的学生id保存到redis中，通过openId区分，登录时通过查redis判断其是否有修改绑定
     * 6、有就不允许登录，等到结果
     * 注意：存放进入redis用map
     * @param studentVO
     * @return
     */
    @PostMapping("/update_bind")
    public R update_bind(StudentVO studentVO,@RequestHeader("Authorization")String token){
        /**
         * 通过获取StudentVo的String,判断是否有null或空值
         */

        String checkString=studentVO.toString().trim();
        log.info(checkString);
        if (checkString.contains("null") || checkString.contains("=,")){
            throw new UnifiedException(ResponseEnum.STUDENT_TEACHER_INFO_NOT_OVER);
        }

        //从redis中获取相关信息
        UserDto userDto= (UserDto) redisTemplate.opsForValue().get(RedisKey.TOKEN+token);
        ConcurrentHashMap<String,Object> map=new ConcurrentHashMap();

        //要将studentVO里的内容进行比对
        Student student=studentService.getById(studentVO.getStuId());
        Assert.notNull(student,ResponseEnum.STUDENT_TEACHER_INFORMATION_NOT_EQUAL);
        Assert.notEquals(student, userDto.getStudent(),ResponseEnum.STUDENT_TEACHER_INFORMATION_NOT_EQUAL);

        /**
         * 将修改绑定的信息，插入到表中
         */
        UpdateBind updateBind=new UpdateBind(userDto.getStudent().getStuId(),
                student.getStuId(),
                userDto.getUser().getId());

        updateBind.setBeforeStuUseId(userTeacherStudentService.getOne(
                new QueryWrapper<UserTeacherStudent>()
                        .eq("use_id", userDto.getUser().getId() )
                        .eq("stu_id",userDto.getStudent().getStuId())
                        .eq("check_state", true)).getStuUseId()
        );
        log.info(updateBind.toString());
        updateBindService.insertUpdateBind(updateBind);

//        deleteStudent_Seat(token);
        return R.ok();
    }

    /**
     * 删除学生座位关系表中原来绑定学生的座位关系
     * @param token
     */
    public void deleteStudent_Seat(String token) {

        UserDto userDto= (UserDto) redisTemplate.opsForValue().get(RedisKey.TOKEN + token);
        userDto.setDto_info("DFL");

        UserTeacherStudent userTeacherStudent=userTeacherStudentService.getOne(new QueryWrapper<UserTeacherStudent>()
                .eq("use_id", userDto.getUser().getId())
                .eq("check_state", true));
        log.info(userDto.toString());
        boolean res = false;
        if (userDto!=null){
            res=studentSeatRelationService.remove(new QueryWrapper<StudentSeatRelation>().eq("stu_use_id", userTeacherStudent.getStuUseId())) ;

            userTeacherStudent.setCheckState(false);
            boolean res1=userTeacherStudentService.update(userTeacherStudent,new UpdateWrapper<UserTeacherStudent>().eq("use_id", userDto.getUser().getId()));
        }else{
            throw new UnifiedException(ResponseEnum.WEIXIN_FETCH_USERINFO_ERROR);
        }
        if (res){
            redisTemplate.delete("student_seat_res"+userDto.getStudent().getStuId());
        }
    }


    /**
     * 学生提交修改信息申请
     * 1、先判断是否有为通过的 检查3
     * 2、将信息插入到申请表中
     *
     * @param studentVO
     * @param token
     * @return
     */
    @PostMapping("/update_information_apply")
    public R update_information_apply(StudentVO studentVO,@RequestHeader("Authorization")String token){
        /**
         * 通过获取StudentVo的String,判断是否有null或空值
         */

        String checkString=studentVO.toString().trim();
        log.info(checkString);
        if (checkString.contains("null") || checkString.contains("=,")){
            throw new UnifiedException(ResponseEnum.STUDENT_TEACHER_INFO_NOT_OVER);
        }

        User user=userService.getUserByOpenId(studentVO.getOpenId());

        UpdateInformation updateInformation1=updateInformationService.getOne(new QueryWrapper<UpdateInformation>()
                .eq("use_id", user.getId())
                .eq("pass_state", 3));
        Assert.isNull(updateInformation1, ResponseEnum.UPDATE_INFORMATION_APPLYED);

        Grade grade=gradeService.getGradeBygraName(studentVO.getGrade());

        UpdateInformation updateInformation=new UpdateInformation(
                studentVO.getStuId().intValue(),
                user.getId(),
                studentVO.getStuName(),
                grade.getGraId(),
                studentVO.getStuPhone().intValue(),
                3
        );
        updateInformationService.save(updateInformation);

        return R.ok();
    }

    @GetMapping("/list")
    public R list(){
        return R.ok().data("list",studentService.getAllStudent());
    }
    @GetMapping("/graName")
    public R graName(String graName){
        return R.ok().data("list",studentService.getAllStudentByGraName(graName));
    }

    @GetMapping("/stuId")
    public R stuId(String stuId){
        return R.ok().data("student",studentService.getStudentVOById(Integer.parseInt(stuId)));
    }

    @GetMapping("/stuName")
    public R stuName(String stuName){
        return R.ok().data("student",studentService.getStudentByStuName(stuName));
    }
}

